package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IFkwzInstitutionService;
import com.ruoyi.system.vo.req.FkwzInstitutionReqVO;
import com.ruoyi.system.vo.req.ImportInstitutionReqDTO;

import com.ruoyi.system.vo.resp.FkwzInstitutionRespVO;
import com.ruoyi.system.vo.resp.TaskRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 重点单位Service业务层处理
 *
 * @author ruoyi
 * @date 2024-05-30
 */
@Slf4j
@Service
public class FkwzInstitutionServiceImpl implements IFkwzInstitutionService {
    @Autowired
    private FkwzInstitutionMapper fkwzInstitutionMapper;



    @Autowired
    private FkwzQuestionTMapper questionTMapper;

    @Autowired
    private FkwzQuestionDetailTMapper questionDetailTMapper;


    @Autowired
    private SysDeptMapper deptMapper;


    @Autowired
    private FkwzTaskMapper taskMapper;

    /**
     * 查询重点单位
     *
     * @param institutionId 重点单位主键
     * @return 重点单位
     */
    @Override
    public FkwzInstitutionRespVO selectFkwzInstitutionByInstitutionId(Long institutionId) {
        return fkwzInstitutionMapper.selectFkwzInstitutionByInstitutionId(institutionId);
    }

    /**
     * 查询重点单位列表
     *
     * @param fkwzInstitution 重点单位
     * @return 重点单位
     */
    @Override
    public List<FkwzInstitutionRespVO> selectFkwzInstitutionList(FkwzInstitutionReqVO fkwzInstitution) {

         LoginUser loginUser = SecurityUtils.getLoginUser();
         SysUser sysUser = loginUser.getSysUser();
        return fkwzInstitutionMapper.selectFkwzInstitutionList(fkwzInstitution,sysUser);
    }

    /**
     * 新增重点单位
     *
     * @param fkwzInstitution 重点单位
     * @return 结果
     */
    @Override
    public int insertFkwzInstitution(FkwzInstitutionReqVO fkwzInstitution) {




        FkwzInstitution selectOne = fkwzInstitutionMapper.selectOne(new LambdaQueryWrapper<FkwzInstitution>()
                .eq(FkwzInstitution::getStatus, 0)
                .eq(FkwzInstitution::getUnifiedSocialCreditCode, fkwzInstitution.getUnifiedSocialCreditCode()));
        if (Objects.nonNull(selectOne)) throw new ServiceException("统一社会信用代码已存在", 405);

        Long policeStationId = fkwzInstitution.getPoliceStationId();
        SysDept sysDept = deptMapper.selectOne(new LambdaQueryWrapper<SysDept>()
                .eq(SysDept::getStatus, 0)
                .eq(SysDept::getDeptId, policeStationId));
        if (!sysDept.getProvinceId().equals(fkwzInstitution.getProvinceId().intValue()) || !sysDept.getCityId().equals(fkwzInstitution.getCityId().intValue())
       || !sysDept.getZoneId().equals(fkwzInstitution.getZoneId().intValue())
//                || !sysDept.getStreetId().equals(fkwzInstitution.getStreetId().intValue())
        ) throw new ServiceException("选择的行政区划和派出所的冲突不予提交!", 405);

//        fkwzInstitution.setProvinceId(sysDept.getProvinceId().longValue());
//        fkwzInstitution.setCityId(sysDept.getCityId().longValue());
//        fkwzInstitution.setZoneId(sysDept.getZoneId().longValue());
        fkwzInstitution.setStreetId(sysDept.getStreetId().longValue());

        fkwzInstitution.setCreateTime(DateUtils.getNowDate());
        fkwzInstitution.setCreateOprUserid(SecurityUtils.getUserId());
        fkwzInstitution.setUpdateTime(DateUtils.getNowDate());
        fkwzInstitution.setUpdateOprUserid(SecurityUtils.getUserId());
        return fkwzInstitutionMapper.insertFkwzInstitution(fkwzInstitution);
    }

    /**
     * 修改重点单位
     *
     * @param fkwzInstitution 重点单位
     * @return 结果
     */
    @Override
    public int updateFkwzInstitution(FkwzInstitutionReqVO fkwzInstitution) {

        FkwzInstitution selectOne = fkwzInstitutionMapper.selectOne(new LambdaQueryWrapper<FkwzInstitution>()
                .ne(FkwzInstitution::getInstitutionId,fkwzInstitution.getInstitutionId())
                .eq(FkwzInstitution::getStatus, 0)
                .eq(FkwzInstitution::getUnifiedSocialCreditCode, fkwzInstitution.getUnifiedSocialCreditCode()));
        if (Objects.nonNull(selectOne)) throw new ServiceException("统一社会信用代码已存在", 405);

        fkwzInstitution.setUpdateTime(DateUtils.getNowDate());
        fkwzInstitution.setUpdateOprUserid(SecurityUtils.getUserId());
        return fkwzInstitutionMapper.updateFkwzInstitution(fkwzInstitution);
    }

    /**
     * 批量删除重点单位
     *
     * @param institutionIds 需要删除的重点单位主键
     * @return 结果
     */
    @Override
    public int deleteFkwzInstitutionByInstitutionIds(Long[] institutionIds) {
        return fkwzInstitutionMapper.deleteFkwzInstitutionByInstitutionIds(institutionIds);
    }

    /**
     * 删除重点单位信息
     *
     * @param institutionId 重点单位主键
     * @return 结果
     */
    @Override
    public int deleteFkwzInstitutionByInstitutionId(Long institutionId) {
        FkwzInstitution fkwzInstitution = new FkwzInstitution();
        fkwzInstitution.setInstitutionId(institutionId);
        fkwzInstitution.setUpdateTime(DateUtils.getNowDate());
        fkwzInstitution.setUpdateOprUserid(SecurityUtils.getUserId());
        fkwzInstitution.setStatus(1);
        int updateById = fkwzInstitutionMapper.updateById(fkwzInstitution);
        return updateById;
    }


    @Override
    public  List<ImportInstitutionReqDTO> importInstitutionTask(MultipartFile file) throws IOException {

        List<ImportInstitutionReqDTO> errorList = new ArrayList<>();
        List<ImportInstitutionReqDTO> normalList = new ArrayList<>();
        List<ImportInstitutionReqDTO> lastList = new ArrayList<>();

        try (InputStream in = file.getInputStream()) {
            //读取excel的文件位置
            List<ImportInstitutionReqDTO> excelData = EasyExcel
                    .read(file.getInputStream())
                    .head(ImportInstitutionReqDTO.class)
                    .sheet()
                    .doReadSync();
            if (CollectionUtil.isEmpty(excelData)) throw new ServiceException("不能导入空白excel!",405);
            if (excelData.size() > 500) throw new ServiceException("不能导入超过五百的数据！",405);

            //过滤重复数据和异常数据 0-异常 1-重复 3-正常
            excelData.stream().forEach(i -> {
                if (StringUtils.isBlank(i.getUnifiedSocialCreditCode())) {
                    ImportInstitutionReqDTO respDto = new ImportInstitutionReqDTO();
                    respDto.setName(i.getName());
                    respDto.setUnifiedSocialCreditCode(i.getUnifiedSocialCreditCode());
                    respDto.setTypeId(0);
                    respDto.setRemark("统一社会信用代码为空。");
                    errorList.add(respDto);
                }
            });

            List<ImportInstitutionReqDTO> filteredData = excelData.stream()
                    .filter(data -> data != null)
                    .filter(data -> data.getUnifiedSocialCreditCode() != null && !data.getUnifiedSocialCreditCode().isEmpty())
                    .map(data -> {
                        data.setTypeId(2);
                        return data;
                    })
                    .distinct()
                    .collect(Collectors.toList());

            // 使用Stream API获取重复统一社会信用代码的数据对象集合
            Map<String, List<ImportInstitutionReqDTO>> duplicatedSocialCreditCodes = excelData.stream()
                    .filter(data -> data != null && data.getUnifiedSocialCreditCode() != null && !data.getUnifiedSocialCreditCode().isEmpty())
                    .collect(Collectors.groupingBy(ImportInstitutionReqDTO::getUnifiedSocialCreditCode));

            // 输出重复统一社会信用代码的数据对象集合
            duplicatedSocialCreditCodes.forEach((key, value) -> {
                if (value.size() > 1) {
                    ImportInstitutionReqDTO reqDTO = value.get(0);
                    ImportInstitutionReqDTO respDto = new ImportInstitutionReqDTO();
                    respDto.setName(reqDTO.getName());
                    respDto.setUnifiedSocialCreditCode(reqDTO.getUnifiedSocialCreditCode());
                    respDto.setTypeId(1);
                    respDto.setRemark("统一社会信用代码重复。");
                    errorList.add(respDto);

                }
            });


            List<String> creditCodeList = filteredData.stream().map(ImportInstitutionReqDTO::getUnifiedSocialCreditCode).collect(Collectors.toList());
            //数据库如果没有这个数据算异常数据
            FkwzInstitutionReqVO fkwzInstitution1 = new FkwzInstitutionReqVO();
            fkwzInstitution1.setCreditCodeList(creditCodeList);
            LoginUser loginUser = SecurityUtils.getLoginUser();
            SysUser sysUser = loginUser.getSysUser();
             List<FkwzInstitutionRespVO> fkwzInstitutionRespVOS = fkwzInstitutionMapper.selectInstitutionList(fkwzInstitution1,sysUser);

            if (CollectionUtil.isNotEmpty(fkwzInstitutionRespVOS)) {
                for (FkwzInstitutionRespVO fkwzInstitution : fkwzInstitutionRespVOS) {
                    ImportInstitutionReqDTO reqDTO = new ImportInstitutionReqDTO();
                    BeanUtils.copyProperties(fkwzInstitution,reqDTO);
                    reqDTO.setTypeId(2);
                    normalList.add(reqDTO);
                }

//                List<ImportInstitutionReqDTO> uniqueData = new ArrayList<>(filteredData);
//                uniqueData.removeAll(normalList);
                filteredData.removeIf(item -> normalList.stream().anyMatch(normalItem -> normalItem.getUnifiedSocialCreditCode().equals(item.getUnifiedSocialCreditCode())));

                if (!filteredData.isEmpty()){
                    for (ImportInstitutionReqDTO uniqueDatum : filteredData) {
                        uniqueDatum.setTypeId(0);
                        uniqueDatum.setRemark("查找不到这个单位数据");
                    }
                }
                errorList.addAll(filteredData);
            } else if (CollectionUtil.isNotEmpty(creditCodeList) && CollectionUtil.isEmpty(fkwzInstitutionRespVOS)) {
                filteredData.forEach(i -> {
                    i.setTypeId(0);
                    i.setRemark("查找不到这个单位数据");
                });
                errorList.addAll(filteredData);
            }
                lastList.addAll(errorList);
            lastList.addAll(normalList);
            lastList = lastList.stream().sorted(Comparator.comparing(ImportInstitutionReqDTO::getTypeId).reversed()).collect(Collectors.toList());

        } catch (ServiceException e) {
            if (e.getCode() == 405) {
              throw e;
            }
        }catch (Exception e) {
            e.printStackTrace();
            log.error("======================================================导入错误！！");
            throw new ServiceException("请检查导入单位数据、导入模板是否正确!",405);
        }
        return lastList;
    }

    @Override
    public FkwzInstitutionRespVO getCheckQuestionnaire(Integer id) {


        TaskRespDTO taskRespDTO = taskMapper.selectFkwzTaskByTaskId(id.longValue());
        FkwzInstitutionRespVO fkwzInstitutionRespVO = fkwzInstitutionMapper.selectFkwzInstitutionByInstitutionId(taskRespDTO.getInstitutionId());
        if (Objects.nonNull(fkwzInstitutionRespVO)) {
            List<FkwzQuestionT> fkwzQuestionTS = questionTMapper
                    .selectList(new LambdaQueryWrapper<FkwzQuestionT>()
                            .eq(FkwzQuestionT::getStatus, 0).eq(FkwzQuestionT::getFormType, fkwzInstitutionRespVO.getTypeId()));

            List<Long> questionIds = fkwzQuestionTS.stream().map(i -> i.getQuestionId()).collect(Collectors.toList());
            List<FkwzQuestionDetailT> fkwzQuestionDetailTS = questionDetailTMapper.selectList(new LambdaQueryWrapper<FkwzQuestionDetailT>()
                    .in(FkwzQuestionDetailT::getQuestionId, questionIds)
                    .eq(FkwzQuestionDetailT::getStatus, 0));

            Map<Long, List<FkwzQuestionDetailT>> collect = fkwzQuestionDetailTS.stream().collect(Collectors.groupingBy(FkwzQuestionDetailT::getQuestionId));
            Set<Map.Entry<Long, List<FkwzQuestionDetailT>>> entries = collect.entrySet();
            for (FkwzQuestionT questionT : fkwzQuestionTS) {
                for (Map.Entry<Long, List<FkwzQuestionDetailT>> entry : entries) {
                    if (questionT.getQuestionId().equals(entry.getKey())) {
                        questionT.setQuestionDetailList(collect.get(entry.getKey()));
                    }
                }
            }

//            FkwzQuestionnaireDictT questionnaireDictT = questionnaireDictTService.getDictByType(fkwzInstitutionRespVO.getTypeId());
            fkwzInstitutionRespVO.setQuestionVOS(fkwzQuestionTS);
            fkwzInstitutionRespVO.setCheckDate(new Date());
            fkwzInstitutionRespVO.setTaskId(taskRespDTO.getTaskId());
            fkwzInstitutionRespVO.setTaskSourceName(taskRespDTO.getTaskSourceName());
        }
        return fkwzInstitutionRespVO;
    }


}
